home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / python2.4 / site-packages / impacket / structure.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2006-06-30  |  21KB  |  708 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.4)
  3.  
  4. from struct import pack, unpack, calcsize
  5.  
  6. class Structure:
  7.     ''' sublcasses can define commonHdr and/or structure.
  8.         each of them is an tuple of either two: (fieldName, format) or three: (fieldName, \':\', class) fields.
  9.         [it can\'t be a dictionary, because order is important]
  10.         
  11.         where format specifies how the data in the field will be converted to/from bytes (string)
  12.         class is the class to use when unpacking \':\' fields.
  13.  
  14.         each field can only contain one value (or an array of values for *)
  15.            i.e. struct.pack(\'Hl\',1,2) is valid, but format specifier \'Hl\' is not (you must use 2 dfferent fields)
  16.  
  17.         format specifiers:
  18.           specifiers from module pack can be used with the same format 
  19.           see struct.__doc__ (pack/unpack is finally called)
  20.             >       [little endian]
  21.             x       [padding byte]
  22.             c       [character]
  23.             b       [signed byte]
  24.             B       [unsigned byte]
  25.             h       [signed short]
  26.             H       [unsigned short]
  27.             l       [signed long]
  28.             L       [unsigned long]
  29.             i       [signed integer]
  30.             I       [unsigned integer]
  31.             q       [signed long long (quad)]
  32.             Q       [unsigned long ong (quad)]
  33.             s       [string (array of chars), must be preceded with length in format specifier, padded with zeros]
  34.             p       [pascal string (includes byte count), must be preceded with length in format specifier, padded with zeros]
  35.             f       [float]
  36.             d       [double]
  37.             =       [native byte ordering, size and alignment]
  38.             @       [native byte ordering, standard size and alignment]
  39.             !       [network byte ordering]
  40.             <       [little endian]
  41.             >       [big endian]
  42.  
  43.           usual printf like specifiers can be used (if started with %) 
  44.           [not recommeneded, there is no why to unpack this]
  45.  
  46.             %08x    will output an 8 bytes hex
  47.             %s      will output a string
  48.             %s\x00  will output a NUL terminated string
  49.             %d%d    will output 2 decimal digits (against the very same specification of Structure)
  50.             ...
  51.  
  52.           some additional format specifiers:
  53.             :       just copy the bytes from the field into the output string (input may be string, other structure, or anything responding to __str__()) (for unpacking, all what\'s left is returned)
  54.             z       same as :, but adds a NUL byte at the end (asciiz) (for unpacking the first NUL byte is used as terminator)  [asciiz string]
  55.             u       same as z, but adds two NUL bytes at the end (after padding to an even size with NULs). (same for unpacking) [unicode string]
  56.             w       DCE-RPC/NDR string (it\'s a macro for [  \'<L=(len(field)+1)/2\',\'"\x00\x00\x00\x00\',\'<L=(len(field)+1)/2\',\':\' ]
  57.             ?-field length of field named \'field\', formated as specified with ? (\'?\' may be \'!H\' for example). The input value overrides the real length
  58.             ?1*?2   array of elements. Each formated as \'?2\', the number of elements in the array is stored as specified by \'?1\' (?1 is optional, or can also be a constant (number), for unpacking)
  59.             \'xxxx   literal xxxx (field\'s value doesn\'t change the output. quotes must not be closed or escaped)
  60.             "xxxx   literal xxxx (field\'s value doesn\'t change the output. quotes must not be closed or escaped)
  61.             _       will not pack the field. Accepts a third argument, which is an unpack code. See _Test_UnpackCode for an example
  62.             ?=packcode  will evaluate packcode in the context of the structure, and pack the result as specified by ?. Unpacking is made plain
  63.             ?&fieldname "Address of field fieldname".
  64.                         For packing it will simply pack the id() of fieldname. Or use 0 if fieldname doesn\'t exists.
  65.                         For unpacking, it\'s used to know weather fieldname has to be unpacked or not, i.e. by adding a & field you turn another field (fieldname) in an optional field.
  66.             
  67.     '''
  68.     commonHdr = ()
  69.     structure = ()
  70.     debug = 0
  71.     
  72.     def __init__(self, data = None, alignment = 0):
  73.         if not hasattr(self, 'alignment'):
  74.             self.alignment = alignment
  75.         
  76.         self.fields = { }
  77.         if data is not None:
  78.             self.fromString(data)
  79.         else:
  80.             self.data = None
  81.  
  82.     
  83.     def setAlignment(self, alignment):
  84.         self.alignment = alignment
  85.  
  86.     
  87.     def setData(self, data):
  88.         self.data = data
  89.  
  90.     
  91.     def packField(self, fieldName, format = None):
  92.         if self.debug:
  93.             print 'packField( %s | %s )' % (fieldName, format)
  94.         
  95.         if format is None:
  96.             format = self.formatForField(fieldName)
  97.         
  98.         if self.fields.has_key(fieldName):
  99.             ans = self.pack(format, self.fields[fieldName], field = fieldName)
  100.         else:
  101.             ans = self.pack(format, None, field = fieldName)
  102.         if self.debug:
  103.             print '\tanswer %r' % ans
  104.         
  105.         return ans
  106.  
  107.     
  108.     def getData(self):
  109.         if self.data is not None:
  110.             return self.data
  111.         
  112.         data = ''
  113.         for field in self.commonHdr + self.structure:
  114.             
  115.             try:
  116.                 data += self.packField(field[0], field[1])
  117.             except Exception:
  118.                 e = None
  119.                 raise 
  120.             except:
  121.                 None if self.fields.has_key(field[0]) else e
  122.  
  123.             if self.alignment:
  124.                 if len(data) % self.alignment:
  125.                     data += '\x00' * self.alignment[:-(len(data) % self.alignment)]
  126.                 
  127.             len(data) % self.alignment
  128.         
  129.         return data
  130.  
  131.     
  132.     def fromString(self, data):
  133.         for field in self.commonHdr + self.structure:
  134.             if self.debug:
  135.                 print 'fromString( %s | %s | %r )' % (field[0], field[1], data)
  136.             
  137.             size = self.calcUnpackSize(field[1], data, field[0])
  138.             dataClassOrCode = str
  139.             if len(field) > 2:
  140.                 dataClassOrCode = field[2]
  141.             
  142.             
  143.             try:
  144.                 self[field[0]] = self.unpack(field[1], data[:size], dataClassOrCode = dataClassOrCode, field = field[0])
  145.             except Exception:
  146.                 e = None
  147.                 e.args += ("When unpacking field '%s | %s | %r[:%d]'" % (field[0], field[1], data, size),)
  148.                 raise 
  149.             except:
  150.                 e
  151.  
  152.             size = self.calcPackSize(field[1], self[field[0]], field[0])
  153.             if self.alignment and size % self.alignment:
  154.                 size += self.alignment - size % self.alignment
  155.             
  156.             data = data[size:]
  157.         
  158.         return self
  159.  
  160.     
  161.     def __setitem__(self, key, value):
  162.         self.fields[key] = value
  163.         self.data = None
  164.  
  165.     
  166.     def __getitem__(self, key):
  167.         return self.fields[key]
  168.  
  169.     
  170.     def __delitem__(self, key):
  171.         del self.fields[key]
  172.  
  173.     
  174.     def __str__(self):
  175.         return self.getData()
  176.  
  177.     
  178.     def __len__(self):
  179.         return len(self.getData())
  180.  
  181.     
  182.     def pack(self, format, data, field = None):
  183.         if self.debug:
  184.             print '  pack( %s | %r | %s)' % (format, data, field)
  185.         
  186.         if field:
  187.             addressField = self.findAddressFieldFor(field)
  188.             if addressField is not None and data is None:
  189.                 return ''
  190.             
  191.         
  192.         if format[:1] == '_':
  193.             return ''
  194.         
  195.         if format[:1] == "'" or format[:1] == '"':
  196.             return format[1:]
  197.         
  198.         two = format.split('&')
  199.         if len(two) == 2:
  200.             
  201.             try:
  202.                 return self.pack(two[0], data)
  203.             if self.fields.has_key(two[1]) and self[two[1]] is not None:
  204.                 return self.pack(two[0], id(self[two[1]]))
  205.             else:
  206.                 return self.pack(two[0], 0)
  207.  
  208.         
  209.         two = format.split('=')
  210.         if len(two) >= 2:
  211.             
  212.             try:
  213.                 return self.pack(two[0], data)
  214.             return self.pack(two[0], eval(two[1], { }, self.fields))
  215.  
  216.         
  217.         two = format.split('-')
  218.         if len(two) == 2:
  219.             
  220.             try:
  221.                 return self.pack(two[0], data)
  222.             return self.pack(two[0], self.calcPackFieldSize(two[1]))
  223.  
  224.         
  225.         two = format.split('*')
  226.         if len(two) == 2:
  227.             answer = ''
  228.             for each in data:
  229.                 answer += self.pack(two[1], each)
  230.             
  231.             if two[0]:
  232.                 if two[0].isdigit():
  233.                     if int(two[0]) != len(data):
  234.                         raise Exception, "Array field has a constant size, and it doesn't match the actual value"
  235.                     
  236.                 else:
  237.                     return self.pack(two[0], len(data)) + answer
  238.             
  239.             return answer
  240.         
  241.         if format[:1] == '%':
  242.             return format % data
  243.         
  244.         if format[:1] == 'z':
  245.             return str(data) + '\x00'
  246.         
  247.         if format[:1] == 'u':
  248.             if not len(data) & 1 or '\x00':
  249.                 pass
  250.             return str(data) + '\x00\x00' + ''
  251.         
  252.         if format[:1] == 'w':
  253.             if len(data) == 0:
  254.                 data = '\x00\x00'
  255.             elif len(data) % 2:
  256.                 data += '\x00'
  257.             
  258.             l = pack('<L', len(data) / 2)
  259.             return '%s\x00\x00\x00\x00%s%s' % (l, l, data)
  260.         
  261.         if data is None:
  262.             raise Exception, 'Trying to pack None'
  263.         
  264.         if format[:1] == ':':
  265.             return str(data)
  266.         
  267.         return pack(format, data)
  268.  
  269.     
  270.     def unpack(self, format, data, dataClassOrCode = str, field = None):
  271.         if self.debug:
  272.             print '  unpack( %s | %r )' % (format, data)
  273.         
  274.         if field:
  275.             addressField = self.findAddressFieldFor(field)
  276.             if addressField is not None:
  277.                 if not self[addressField]:
  278.                     return None
  279.                 
  280.             
  281.         
  282.         if format[:1] == '_':
  283.             if dataClassOrCode != str:
  284.                 return eval(dataClassOrCode, { }, self.fields)
  285.             
  286.         
  287.         if format[:1] == "'" or format[:1] == '"':
  288.             answer = format[1:]
  289.             if answer != data:
  290.                 raise Exception, "Unpacked data doesn't match constant value '%r' should be '%r'" % (data, answer)
  291.             
  292.             return answer
  293.         
  294.         two = format.split('&')
  295.         if len(two) == 2:
  296.             return self.unpack(two[0], data)
  297.         
  298.         two = format.split('=')
  299.         if len(two) >= 2:
  300.             return self.unpack(two[0], data)
  301.         
  302.         two = format.split('-')
  303.         if len(two) == 2:
  304.             return self.unpack(two[0], data)
  305.         
  306.         two = format.split('*')
  307.         if len(two) == 2:
  308.             answer = []
  309.             sofar = 0
  310.             if two[0].isdigit():
  311.                 number = int(two[0])
  312.             elif two[0]:
  313.                 sofar += self.calcUnpackSize(two[0], data)
  314.                 number = self.unpack(two[0], data[:sofar])
  315.             else:
  316.                 number = -1
  317.             while number and sofar < len(data):
  318.                 nsofar = sofar + self.calcUnpackSize(two[1], data[sofar:])
  319.                 answer.append(self.unpack(two[1], data[sofar:nsofar], dataClassOrCode))
  320.                 number -= 1
  321.                 sofar = nsofar
  322.             return answer
  323.         
  324.         if format[:1] == '%':
  325.             return format % data
  326.         
  327.         if format == 'z':
  328.             if data[-1] != '\x00':
  329.                 raise Exception, "%s 'z' field is not NUL terminated: %r" % (field, data)
  330.             
  331.             return data[:-1]
  332.         
  333.         if format == 'u':
  334.             if data[-2:] != '\x00\x00':
  335.                 raise Exception, "%s 'u' field is not NUL-NUL terminated: %r" % (field, data)
  336.             
  337.             return data[:-2]
  338.         
  339.         if format == 'w':
  340.             l = unpack('<L', data[:4])[0]
  341.             return data[12:12 + l * 2]
  342.         
  343.         if format == ':':
  344.             return dataClassOrCode(data)
  345.         
  346.         return unpack(format, data)[0]
  347.  
  348.     
  349.     def calcPackSize(self, format, data, field = None):
  350.         if field:
  351.             addressField = self.findAddressFieldFor(field)
  352.             if addressField is not None:
  353.                 if not self[addressField]:
  354.                     return 0
  355.                 
  356.             
  357.         
  358.         if format[:1] == '_':
  359.             return 0
  360.         
  361.         if format[:1] == "'" or format[:1] == '"':
  362.             return len(format) - 1
  363.         
  364.         two = format.split('&')
  365.         if len(two) == 2:
  366.             return self.calcPackSize(two[0], data)
  367.         
  368.         two = format.split('=')
  369.         if len(two) >= 2:
  370.             return self.calcPackSize(two[0], data)
  371.         
  372.         two = format.split('-')
  373.         if len(two) == 2:
  374.             return self.calcPackSize(two[0], data)
  375.         
  376.         two = format.split('*')
  377.         if len(two) == 2:
  378.             answer = 0
  379.             if two[0].isdigit():
  380.                 if int(two[0]) != len(data):
  381.                     raise Exception, "Array field has a constant size, and it doesn't match the actual value"
  382.                 
  383.             elif two[0]:
  384.                 answer += self.calcPackSize(two[0], len(data))
  385.             
  386.             for each in data:
  387.                 answer += self.calcPackSize(two[1], each)
  388.             
  389.             return answer
  390.         
  391.         if format[:1] == '%':
  392.             return len(format % data)
  393.         
  394.         if format[:1] == 'z':
  395.             return len(data) + 1
  396.         
  397.         if format[:1] == 'u':
  398.             l = len(data)
  399.             if not l & 1 or 3:
  400.                 pass
  401.             return l + 2
  402.         
  403.         if format[:1] == 'w':
  404.             l = len(data)
  405.             return 12 + l + l % 2
  406.         
  407.         if format[:1] == ':':
  408.             return len(data)
  409.         
  410.         return calcsize(format)
  411.  
  412.     
  413.     def calcUnpackSize(self, format, data, field = None):
  414.         if self.debug:
  415.             print '  calcUnpackSize( %s | %s | %r)' % (field, format, data)
  416.         
  417.         addressField = self.findAddressFieldFor(field)
  418.         if addressField is not None:
  419.             if not self[addressField]:
  420.                 return 0
  421.             
  422.         
  423.         
  424.         try:
  425.             lengthField = self.findLengthFieldFor(field)
  426.             return self[lengthField]
  427.         except:
  428.             pass
  429.  
  430.         if format[:1] == '_':
  431.             return 0
  432.         
  433.         if format[:1] == "'" or format[:1] == '"':
  434.             return len(format) - 1
  435.         
  436.         two = format.split('&')
  437.         if len(two) == 2:
  438.             return self.calcUnpackSize(two[0], data)
  439.         
  440.         two = format.split('=')
  441.         if len(two) >= 2:
  442.             return self.calcUnpackSize(two[0], data)
  443.         
  444.         two = format.split('-')
  445.         if len(two) == 2:
  446.             return self.calcUnpackSize(two[0], data)
  447.         
  448.         two = format.split('*')
  449.         if len(two) == 2:
  450.             answer = 0
  451.             if two[0]:
  452.                 if two[0].isdigit():
  453.                     number = int(two[0])
  454.                 else:
  455.                     answer += self.calcUnpackSize(two[0], data)
  456.                     number = self.unpack(two[0], data[:answer])
  457.                 while number:
  458.                     number -= 1
  459.                     answer += self.calcUnpackSize(two[1], data[answer:])
  460.             else:
  461.                 while answer < len(data):
  462.                     answer += self.calcUnpackSize(two[1], data[answer:])
  463.             return answer
  464.         
  465.         if format[:1] == '%':
  466.             raise Exception, "Can't guess the size of a printf like specifier for unpacking"
  467.         
  468.         if format[:1] == 'z':
  469.             return data.index('\x00') + 1
  470.         
  471.         if format[:1] == 'u':
  472.             l = data.index('\x00\x00')
  473.             if not l & 1 or 3:
  474.                 pass
  475.             return l + 2
  476.         
  477.         if format[:1] == 'w':
  478.             l = unpack('<L', data[:4])[0]
  479.             return 12 + l * 2
  480.         
  481.         if format[:1] == ':':
  482.             return len(data)
  483.         
  484.         return calcsize(format)
  485.  
  486.     
  487.     def calcPackFieldSize(self, fieldName, format = None):
  488.         if format is None:
  489.             format = self.formatForField(fieldName)
  490.         
  491.         return self.calcPackSize(format, self[fieldName])
  492.  
  493.     
  494.     def formatForField(self, fieldName):
  495.         for field in self.commonHdr + self.structure:
  496.             if field[0] == fieldName:
  497.                 return field[1]
  498.                 continue
  499.         
  500.         raise Exception, 'Field %s not found' % fieldName
  501.  
  502.     
  503.     def findAddressFieldFor(self, fieldName):
  504.         descriptor = '&%s' % fieldName
  505.         l = len(descriptor)
  506.         for field in self.commonHdr + self.structure:
  507.             if field[1][-l:] == descriptor:
  508.                 return field[0]
  509.                 continue
  510.         
  511.  
  512.     
  513.     def findLengthFieldFor(self, fieldName):
  514.         descriptor = '-%s' % fieldName
  515.         l = len(descriptor)
  516.         for field in self.commonHdr + self.structure:
  517.             if field[1][-l:] == descriptor:
  518.                 return field[0]
  519.                 continue
  520.         
  521.  
  522.     
  523.     def zeroValue(self, format):
  524.         two = format.split('*')
  525.         if len(two) == 2:
  526.             if two[0].isdigit():
  527.                 return (self.zeroValue(two[1]),) * int(two[0])
  528.             
  529.         
  530.         if not format.find('*') == -1:
  531.             return ()
  532.         
  533.         if 's' in format:
  534.             return ''
  535.         
  536.         if format in [
  537.             'z',
  538.             ':',
  539.             'u']:
  540.             return ''
  541.         
  542.         if format == 'w':
  543.             return '\x00\x00'
  544.         
  545.         return 0
  546.  
  547.     
  548.     def clear(self):
  549.         for field in self.commonHdr + self.structure:
  550.             self[field[0]] = self.zeroValue(field[1])
  551.         
  552.  
  553.     
  554.     def dump(self, msg, indent = 0):
  555.         import types as types
  556.         ind = ' ' * indent
  557.         print '\n%s' % msg
  558.         for i in self.fields.keys():
  559.             if isinstance(self[i], Structure):
  560.                 self[i].dump('%s:{' % i, indent = indent + 4)
  561.                 print '}'
  562.                 continue
  563.             print '%s%s: {%r}' % (ind, i, self[i])
  564.         
  565.  
  566.  
  567.  
  568. class _StructureTest:
  569.     alignment = 0
  570.     
  571.     def create(self, data = None):
  572.         if data is not None:
  573.             return self.theClass(data, alignment = self.alignment)
  574.         else:
  575.             return self.theClass(alignment = self.alignment)
  576.  
  577.     
  578.     def run(self):
  579.         print 
  580.         print '-' * 70
  581.         testName = self.__class__.__name__
  582.         print 'starting test: %s.....' % testName
  583.         a = self.create()
  584.         self.populate(a)
  585.         a.dump('packing.....')
  586.         a_str = str(a)
  587.         print 'packed: %r' % a_str
  588.         print 'unpacking.....'
  589.         b = self.create(a_str)
  590.         b.dump('unpacked.....')
  591.         print 'repacking.....'
  592.         b_str = str(b)
  593.         if b_str != a_str:
  594.             print "ERROR: original packed and repacked don't match"
  595.             print 'packed: %r' % b_str
  596.         
  597.  
  598.  
  599.  
  600. class _Test_simple(_StructureTest):
  601.     
  602.     class theClass(Structure):
  603.         commonHdr = ()
  604.         structure = (('int1', '!L'), ('len1', '!L-z1'), ('arr1', 'B*<L'), ('z1', 'z'), ('u1', 'u'), ('', '"COCA'), ('len2', '!H-:1'), ('', '"COCA'), (':1', ':'), ('int3', '>L'), ('code1', '>L=len(arr1)*2+0x1000'))
  605.  
  606.     
  607.     def populate(self, a):
  608.         a['default'] = 'hola'
  609.         a['int1'] = 12593
  610.         a['int3'] = 1162101570
  611.         a['z1'] = 'hola'
  612.         a['u1'] = 'hola'.encode('utf_16_le')
  613.         a[':1'] = ':1234:'
  614.         a['arr1'] = (305402420, 0x88990077L, 1094795585)
  615.  
  616.  
  617.  
  618. class _Test_fixedLength(_Test_simple):
  619.     
  620.     def populate(self, a):
  621.         _Test_simple.populate(self, a)
  622.         a['len1'] = 1111638594
  623.  
  624.  
  625.  
  626. class _Test_simple_aligned4(_Test_simple):
  627.     alignment = 4
  628.  
  629.  
  630. class _Test_nested(_StructureTest):
  631.     
  632.     class theClass(Structure):
  633.         
  634.         class _Inner(Structure):
  635.             structure = (('data', 'z'),)
  636.  
  637.         structure = (('nest1', ':', _Inner), ('nest2', ':', _Inner), ('int', '<L'))
  638.  
  639.     
  640.     def populate(self, a):
  641.         a['nest1'] = _Test_nested.theClass._Inner()
  642.         a['nest2'] = _Test_nested.theClass._Inner()
  643.         a['nest1']['data'] = 'hola manola'
  644.         a['nest2']['data'] = 'chau loco'
  645.         a['int'] = 305419896
  646.  
  647.  
  648.  
  649. class _Test_Optional(_StructureTest):
  650.     
  651.     class theClass(Structure):
  652.         structure = (('pName', '<L&Name'), ('pList', '<L&List'), ('Name', 'w'), ('List', '<H*<L'))
  653.  
  654.     
  655.     def populate(self, a):
  656.         a['Name'] = 'Optional test'
  657.         a['List'] = (1, 2, 3, 4)
  658.  
  659.  
  660.  
  661. class _Test_Optional_sparse(_Test_Optional):
  662.     
  663.     def populate(self, a):
  664.         _Test_Optional.populate(self, a)
  665.         del a['Name']
  666.  
  667.  
  668.  
  669. class _Test_AsciiZArray(_StructureTest):
  670.     
  671.     class theClass(Structure):
  672.         structure = (('head', '<L'), ('array', 'B*z'), ('tail', '<L'))
  673.  
  674.     
  675.     def populate(self, a):
  676.         a['head'] = 4660
  677.         a['tail'] = 43981
  678.         a['array'] = ('hola', 'manola', 'te traje')
  679.  
  680.  
  681.  
  682. class _Test_UnpackCode(_StructureTest):
  683.     
  684.     class theClass(Structure):
  685.         structure = (('leni', '<L=len(uno)*2'), ('cuchi', '_-uno', 'leni/2'), ('uno', ':'), ('dos', ':'))
  686.  
  687.     
  688.     def populate(self, a):
  689.         a['uno'] = 'soy un loco!'
  690.         a['dos'] = 'que haces fiera'
  691.  
  692.  
  693. if __name__ == '__main__':
  694.     _Test_simple().run()
  695.     
  696.     try:
  697.         _Test_fixedLength().run()
  698.     except:
  699.         print 'cannot repack because length is bogus'
  700.  
  701.     _Test_simple_aligned4().run()
  702.     _Test_nested().run()
  703.     _Test_Optional().run()
  704.     _Test_Optional_sparse().run()
  705.     _Test_AsciiZArray().run()
  706.     _Test_UnpackCode().run()
  707.  
  708.